package KUtilities;

import java.awt.Component;
import java.awt.Dimension;
import java.awt.Point;
import javax.swing.JComponent;
import javax.swing.Spring;
import javax.swing.SpringLayout;
import javax.swing.SwingUtilities;

public class KSpringOld extends SpringLayout
{
	private JComponent parent;
	
	/**
	 * Creates a SpringLayout with some extra utilities
	 */
	public KSpringOld()
	{
		super();
	}
	
	/**
	 * Creates and Adds a SpringLayout to the Specified Component with some extra utilities
	 * @param parent : component this SpringLayout is set for
	 */
	public KSpringOld(JComponent parent)
	{
		parent.removeAll();
		parent.setLayout(this);
		this.parent=parent;
	}
	
	/**
	 * Add the <code>components</code> to the container
	 * @param components : components to add
	 */
	public void add(JComponent...components)
	{
		KSwing.addComponents(parent,components);
	}
	
	/**
	 * Add Components to the center
	 * @param components components to add
	 */
	public void addToCenter(JComponent... components)
	{
		Component prevComps[] =parent.getComponents();
		if(parent.getComponentCount()==0)
		{
			parent.add(components[0]);
			putConstraint(VERTICAL_CENTER,components[0],0,VERTICAL_CENTER,parent);
			putConstraint(HORIZONTAL_CENTER,components[0],0,HORIZONTAL_CENTER,parent);
		}
		else
		{
			Component temp=parent.getComponent(0);
			parent.add(components[0]);
			putConstraint(VERTICAL_CENTER,components[0],0,VERTICAL_CENTER,temp);
			putConstraint(HORIZONTAL_CENTER,components[0],0,HORIZONTAL_CENTER,temp);
		}
		for(int i=1;i<components.length;i++)
		{
			parent.add(components[i]);
			putConstraint(VERTICAL_CENTER,components[i],0,VERTICAL_CENTER,components[i-1]);
			putConstraint(HORIZONTAL_CENTER,components[i],0,HORIZONTAL_CENTER,components[i-1]);
		}
		int maxWidth=Math.max(parent.getPreferredSize().width, components[0].getPreferredSize().width);
		int maxHeight=Math.max(parent.getPreferredSize().height, components[0].getPreferredSize().height);
		for(int i=1;i<components.length;i++)
		{
			maxWidth=Math.max(maxWidth, components[i].getPreferredSize().width);
			maxHeight=Math.max(maxHeight, components[i].getPreferredSize().height);
		}
		
		parent.setPreferredSize(new Dimension(maxWidth,maxHeight));
		
		int length=components.length;
		int i;
		for(i=0;i<length;i++)
		{
			parent.setComponentZOrder(components[i], length-i-1);
		}
		for(int j=0;j<prevComps.length;j++)
		{
			parent.setComponentZOrder(prevComps[j], i++);
		}
		SwingUtilities.updateComponentTreeUI(KSwing.gui);
	}
	
	/**
	 * Remove the <code>components</code> from the container
	 * @param components : components to remove
	 */
	public void remove(JComponent...components)
	{
		for(int i=0;i<components.length;i++){
			parent.remove(components[i]);
		}
		SwingUtilities.updateComponentTreeUI(KSwing.gui);
	}
	
	/**
	 * Removes all components in the container
	 */
	public void removeAll()
	{
		Component components[]=parent.getComponents();
		for(int i=0;i<components.length;i++){
			parent.remove(components[i]);
		}
		SwingUtilities.updateComponentTreeUI(KSwing.gui);
	}
	
	/**
	 * Gets the <code>width spring</code> of the specified <code>component</code>
     * @param   component : component to get width
	 */
	public Spring getWidth(JComponent component)
	{
		return getConstraints(component).getWidth();
	}
	
	/**
	 * Sets the <code>width</code> of the specified <code>component</code>
     * @param   component : component to set new width
     * @param   width : new width of the component
	 */
	public void setWidth(JComponent component,int width)
	{
		setWidth(component,Spring.constant(width));
	}
	
	/**
	 * Sets the <code>width</code> of the specified <code>component</code> based on specified minimum, preferred and maximum values
     * @param   component : component to set new width
     * @param   min : minimum width of the component
     * @param   pref : preferred width of the component
     * @param   max : maximum width of the component
	 */
	public void setWidth(JComponent component,int min,int pref,int max)
	{
		setWidth(component,Spring.constant(min,pref,max));
	}
	
	/**
	 * Sets the <code>width spring</code> of the specified <code>component</code>
     * @param   component : component to set new width
     * @param   width : new width spring of the component
	 */
	public void setWidth(JComponent component,Spring width)
	{
		getConstraints(component).setWidth(width);
	}

	/**
	 * Gets the <code>height spring</code> of the specified <code>component</code>
     * @param   component : component to get height
	 */
	public Spring getHeight(JComponent component)
	{
		return getConstraints(component).getHeight();
	}
	
	/**
	 * Sets the <code>height</code> of the specified <code>component</code>
     * @param   component : component to set new height
     * @param   height : new height of the component
	 */
	public void setHeight(JComponent component,int height)
	{
		setHeight(component,Spring.constant(height));
	}
	
	/**
	 * Sets the <code>height</code> of the specified <code>component</code> based on specified minimum, preferred and maximum values
     * @param   component : component to set new height
     * @param   min : minimum height of the component
     * @param   pref : preferred height of the component
     * @param   max : maximum height of the component
	 */
	public void setHeight(JComponent component,int min,int pref,int max)
	{
		setHeight(component,Spring.constant(min,pref,max));
	}
	
	/**
	 * Sets the <code>height spring</code> of the specified <code>component</code>
     * @param   component : Component to set new height
     * @param   height : new height spring of the Component
	 */
	public void setHeight(JComponent component,Spring height)
	{
		getConstraints(component).setHeight(height);
	}
	
	/**
	 * Links the <code>widths</code> of the specified <code>components</code> so all of them have equal <code>width</code>
     * @param   components : components to link width
	 */
	public void linkWidth(JComponent...components)
	{
		Spring maxWidth=getConstraints(components[0]).getWidth();
		for(int i=1;i<components.length;i++)
		{
			maxWidth=Spring.max(maxWidth, getConstraints(components[i]).getWidth());
		}
		for(int i=0;i<components.length;i++)
		{
			setWidth(components[i],maxWidth);
		}
	}
	
	/**
	 * Links the <code>heights</code> of the specified <code>components</code> so all of them have equal <code>height</code>
     * @param   components : components to link height
	 */
	public void linkHeight(JComponent...components)
	{
		Spring maxHeight=getConstraints(components[0]).getHeight();
		for(int i=1;i<components.length;i++)
		{
			maxHeight=Spring.max(maxHeight, getConstraints(components[i]).getHeight());
		}
		for(int i=0;i<components.length;i++)
		{
			setHeight(components[i],maxHeight);
		}
	}
	
	/**
	 * Sets the <code>width</code> and <code>height</code> of the specified <code>component</code>
     * @param   component : component to resize
     * @param   width : new width of the Component
     * @param   height : new height of the Component
	 */
	public void setSize(JComponent component,int width,int height)
	{
		setWidth(component,width);
		setHeight(component,height);
	}
	
	/**
	 * Sets the <code>size</code> and <code>height</code> of the specified <code>component</code>
     * @param   component : component to resize
     * @param   size : new dimension of the Component
	 */
	public void setSize(JComponent component,Dimension size)
	{
		setSize(component,size.width,size.height);
	}
	
	/**
	 * Sets the <code>width</code> and <code>height</code> of the specified <code>component</code>
     * @param   component : component to resize
     * @param   width : new width spring of the Component
     * @param   height : new height spring of the Component
	 */
	public void setSize(JComponent component,Spring width,Spring height)
	{
		setWidth(component,width);
		setHeight(component,height);
	}
	
	/**
	 * Links the <code>sizes</code> of the specified <code>components</code> so all of them have equal <code>size (width and height)</code>
     * @param   components : components to link size
	 */
	public void linkSize(JComponent...components)
	{
		linkWidth(components);
		linkHeight(components);
	}
	
	/**
	 * Gets the <code>x-coordinate spring</code> of the specified <code>component</code>
     * @param   component : component to find x-coordinate
	 */
	public Spring getX(JComponent component)
	{
		return getConstraints(component).getX();
	}
	
	/**
	 * Sets the <code>x-coordinate</code> of the specified <code>component</code>
     * @param   component : component to relocate
     * @param   x : x-coordinate of new location
     */
	public void setX(JComponent component,int x)
	{
		setX(component,Spring.constant(x));
	}
	
	/**
	 * Sets the <code>x-coordinate</code> of the specified <code>component</code> based on specified minimum, preferred and maximum values
     * @param   component : component to relocate
	 * @param   min : minimum x-coordinate of new location
     * @param   pref : preferred x-coordinate of new location
     * @param   max : maximum x-coordinate of new location
	 */
	public void setX(JComponent component,int min,int pref,int max)
	{
		setX(component,Spring.constant(min,pref,max));
	}
	
	/**
	 * Sets the <code>x-coordinate spring</code> of the specified <code>component</code>
     * @param   component : component to relocate
     * @param   x : x-coordinate spring of new location
	 */
	public void setX(JComponent component,Spring x)
	{
		getConstraints(component).setX(x);
	}
	
	/**
	 * Gets the <code>y-coordinate spring</code> of the specified <code>component</code>
     * @param   component : component to find y-coordinate
	 */
	public Spring getY(JComponent component)
	{
		return getConstraints(component).getY();
	}
	
	/**
	 * Sets the <code>y-coordinate</code> of the specified <code>component</code>
     * @param   component : component to relocate
     * @param   y : y-coordinate of new location
     */
	public void setY(JComponent component,int y)
	{
		setY(component,Spring.constant(y));
	}
	
	/**
	 * Sets the <code>y-coordinate</code> of the specified <code>component</code> based on specified minimum, preferred and maximum values
     * @param   component : component to relocate
	 * @param   min : minimum y-coordinate of new location
     * @param   pref : preferred y-coordinate of new location
     * @param   max : maximum y-coordinate of new location
	 */
	public void setY(JComponent component,int min,int pref,int max)
	{
		setY(component,Spring.constant(min,pref,max));
	}
	
	/**
	 * Sets the <code>y-coordinate spring</code> of the specified <code>component</code>
     * @param   component : component to relocate
     * @param   y : y-coordinate spring of new location
	 */
	public void setY(JComponent component,Spring y)
	{
		getConstraints(component).setY(y);
	}

	/**
	 * Sets the <code>x-coordinate</code> and <code>y-coordinate</code> of the specified <code>component</code>
     * @param   component : component to relocate
     * @param 	x : x-coordinate of new location
     * @param   y : y-coordinate of new location
	 */
	public void setLocation(JComponent component,int x,int y)
	{
		setX(component,x);
		setY(component,y);
	}
	
	/**
	 * Sets the <code>location</code> of the specified <code>component</code>
     * @param   component : component to relocate
     * @param 	location : point of the new location
	 */
	public void setLocation(JComponent component,Point location)
	{
		setLocation(component,location.x,location.y);
	}
	
	/**
	 * Aligns all <code>components</code> to the <code>Top</code>
     * @param   components : components to align Top
	 */
	public void alignTop(JComponent...components)
	{
		for(int i=1;i<components.length;i++)
		{
			putConstraint("North",components[i],0,"North",components[i-1]);
		}
	}
	
	/**
	 * Aligns all <code>components</code> to the <code>Bottom</code>
     * @param   components : components to align Bottom
	 */
	public void alignBottom(JComponent...components)
	{
		for(int i=1;i<components.length;i++)
		{
			putConstraint("South",components[i],0,"South",components[i-1]);
		}
	}
	
	/**
	 * Aligns all <code>components</code> to the <code>Left</code>
     * @param   components : components to align Left
	 */
	public void alignLeft(JComponent...components)
	{
		for(int i=1;i<components.length;i++)
		{
			putConstraint("West",components[i],0,"West",components[i-1]);
		}
	}
	
	/**
	 * Aligns all <code>components</code> to the <code>Right</code>
     * @param   components : components to align Right
	 */
	public void alignRight(JComponent...components)
	{
		for(int i=1;i<components.length;i++)
		{
			putConstraint("East",components[i],0,"East",components[i-1]);
		}
	}
	
	/**
	 * Aligns all <code>components</code> to the center<code>Vertically</code>
     * @param   components : components to align Center
	 */
	public void alignVerticalCenter(JComponent...components)
	{
		for(int i=1;i<components.length;i++)
		{
			JComponent big,small;
			big=components[i];
			small=components[i-1];
			if(getWidth(small).getValue()>getWidth(big).getValue())
			{
				big=components[i-1];
				small=components[i];
			}
			putConstraint(HORIZONTAL_CENTER,small,0,HORIZONTAL_CENTER,big);
		}
	}
	
	/**
	 * Aligns all <code>components</code> to the center<code>Horizontally</code>
     * @param   components : components to align Center
	 */
	public void alignHorizontalCenter(JComponent...components)
	{
		for(int i=1;i<components.length;i++)
		{
			JComponent big,small;
			big=components[i];
			small=components[i-1];
			if(getWidth(small).getValue()>getWidth(big).getValue())
			{
				big=components[i-1];
				small=components[i];
			}
			putConstraint(VERTICAL_CENTER,small,0,VERTICAL_CENTER,big);
		}
	}
	
	/**
	 * Aligns <code>components</code> horizontally on Top and Bottom
	 * @param components : components to align horizontally
	 */
	public void alignHorizontal(JComponent...components)
	{
		alignTop(components);
		linkHeight(components);
	}
	
	/**
	 * Links <code>North and South</code> of all components
	 * @param components : components to link North and South
	 */
	public void linkHorizontal(JComponent...components)
	{
		alignTop(components);
		alignBottom(components);
	}
	
	/**
	 * Aligns <code>components</code> vertically on Left and Right 
	 * @param components : components to place vertically
	 */
	public void alignVertical(JComponent...components)
	{
		alignLeft(components);
		linkWidth(components);
	}
	
	/**
	 * Links <code>East and West</code> of all components
	 * @param components : components to link East and West
	 */
	public void linkVertical(JComponent...components)
	{
		alignRight(components);
		alignLeft(components);
	}
	
	/**
	 * Add <code>horizontal gap</code> between specified <code>components</code>
	 * @param gap : gap required between components
	 * @param components : components to add gap in between
	 */
	public void setHGap(int gap,JComponent...components)
	{
		setHGap(Spring.constant(gap),components);
	}
	
	/**
	 * Add <code>horizontal gap</code> between specified <code>components</code> based on specified minimum, preferred and maximum values
	 * @param min : minimum gap required between components
	 * @param pref : preferred gap required between components
	 * @param max : maximum gap required between components
	 * @param components : components to add gap in between
	 */
	public void setHGap(int min,int pref,int max,JComponent...components)
	{
		setHGap(Spring.constant(min,pref,max),components);
	}
	
	/**
	 * Add <code>horizontal gap spring</code> between specified <code>components</code>
	 * @param gap : gap spring required between components
	 * @param components : components to add gap in between
	 */
	public void setHGap(Spring gap,JComponent...components)
	{
		for(int i=1;i<components.length;i++)
		{
			if(components[i-1]==components[i].getParent())
				putConstraint("West",components[i],gap,"West",components[i-1]);
			else if(components[i]==components[i-1].getParent())
				putConstraint("East",components[i],gap,"East",components[i-1]);
			else
				putConstraint("West",components[i],gap,"East",components[i-1]);
		}
	}

	/**
	 * Add <code>vertical gap</code> between specified <code>components</code>
	 * @param gap : gap required between components
	 * @param components : components to add gap in between
	 */
	public void setVGap(int gap,JComponent...components)
	{
		setVGap(Spring.constant(gap),components);
	}
	
	/**
	 * Add <code>vertical gap</code> between specified <code>components</code> based on specified minimum, preferred and maximum values
	 * @param min : minimum gap required between components
	 * @param pref : preferred gap required between components
	 * @param max : maximum gap required between components
	 * @param components : components to add gap in between
	 */
	public void setVGap(int min,int pref,int max,JComponent...components)
	{
		setVGap(Spring.constant(min,pref,max),components);
	}
	
	/**
	 * Add <code>vertical gap spring</code> between specified <code>components</code>
	 * @param gap : gap spring required between components
	 * @param components : components to add gap in between
	 */
	public void setVGap(Spring gap,JComponent...components)
	{
		for(int i=1;i<components.length;i++)
		{
			if(components[i-1]==components[i].getParent())
				putConstraint("North",components[i],gap,"North",components[i-1]);
			else if(components[i]==components[i-1].getParent())
				putConstraint("South",components[i],gap,"South",components[i-1]);
			else
				putConstraint("North",components[i],gap,"South",components[i-1]);
		}
	}	
	
	public void addSingleToCenter(JComponent component)
	{
		parent.add(component);
		putConstraint(VERTICAL_CENTER,component,0,VERTICAL_CENTER,parent);
		putConstraint(HORIZONTAL_CENTER,component,0,HORIZONTAL_CENTER,parent);
		parent.setPreferredSize(component.getPreferredSize());
	}
}
